import os
import pickle
import tempfile
import shutil
import copy

from lockfile import FileLock

#############################################################################
# Stores are objects that have dictionaries that can be saved. Users of the
# store can get the dictionary by calling the use() method on the store, and
# when they have done their changes, they can call the save() method.
#############################################################################

class InMemoryStore(object):
    """A store that just saves all data in memory.

    Keeps the data in memory, and makes a deep copy of it when saving. This is
    mostly useful for testing, as the data is obviously lost when the
    application exits. You can see what was saved by looking at the saves
    attribute, which is a list of all saved data.

    You can set the starting data with the 'data' argument to the __init__
    method.
    """
    def __init__(self, data=None):
        self.data = data if data != None else {}
        self.saves = []

    def use(self):
        return self.data
    
    def save(self):
        self.saves.append(copy.deepcopy(self.data))


class PickleFileStore(object):
    """A store that, when saved, pickles the data into a file. """

    def __init__(self, filename):
        self.filename = filename
        self.dir = os.path.dirname(filename)

        try:
            with open(self.filename, 'r') as f:
                self.data = pickle.load(f)
        except IOError:
            self.data = {}

    def use(self):
        return self.data

    def save(self):
        tmp = tempfile.NamedTemporaryFile('w', dir=self.dir, delete=False)
        pickle.dump(self.data, tmp)
        tmp.close()

        shutil.move(tmp.name, self.filename)
